---
title: "Spring Jpa"
date: 2019-5-20
categories:
- java
- spring-amqp
- spring-jpa
tags:
---

<div id="content">
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#org825f104">Criteria API</a></li>
<li><a href="#orgc427e4a">Specification</a></li>
</ul>
</div>
</div>
<div class="outline-2" id="outline-container-org825f104">
<h2 id="org825f104">Criteria API</h2>
<div class="outline-text-2" id="text-org825f104">
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">条件 birthday 的值</span>
<span style="font-weight: bold; text-decoration: underline;">LocalDate</span> <span style="font-weight: bold; font-style: italic;">today</span> = <span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">LocalDate</span>();
<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">创建条件所需的对象</span>
<span style="font-weight: bold; text-decoration: underline;">CriteriaBuilder</span> <span style="font-weight: bold; font-style: italic;">builder</span> = em.getCriteriaBuilder();
<span style="font-weight: bold; text-decoration: underline;">CriteriaQuery</span>&lt;<span style="font-weight: bold; text-decoration: underline;">Customer</span>&gt; <span style="font-weight: bold; font-style: italic;">query</span> = builder.createQuery(Customer.<span style="font-weight: bold;">class</span>);
<span style="font-weight: bold; text-decoration: underline;">Root</span>&lt;<span style="font-weight: bold; text-decoration: underline;">Customer</span>&gt; <span style="font-weight: bold; font-style: italic;">root</span> = query.from(Customer.<span style="font-weight: bold;">class</span>);
<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">第一个条件：birthday=today</span>
<span style="font-weight: bold; text-decoration: underline;">Predicate</span> <span style="font-weight: bold; font-style: italic;">hasBirthday</span> = builder.equal(root.get(Customer_.birthday), today);
<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">第二个条件：createAt&lt;(2 years ago)</span>
<span style="font-weight: bold; text-decoration: underline;">Predicate</span> <span style="font-weight: bold; font-style: italic;">isLongTermCustomer</span> = builder.lessThan(root.get(Customer_.createdAt), today.minusYears(2)); 
<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">条件一 and 条件二</span>
query.where(builder.and(hasBirthday, isLongTermCustomer));
<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">get list</span>
em.createQuery(query.select(root)).getResultList();

</pre>
</div>
</div>
</div>
<div class="outline-2" id="outline-container-orgc427e4a">
<h2 id="orgc427e4a">Specification</h2>
<div class="outline-text-2" id="text-orgc427e4a">
<p>
A specification as a predicate over an entity:
</p>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">public</span> <span style="font-weight: bold;">interface</span> <span style="font-weight: bold; text-decoration: underline;">Specification</span>&lt;<span style="font-weight: bold; text-decoration: underline;">T</span>&gt; {
  <span style="font-weight: bold; text-decoration: underline;">Predicate</span> <span style="font-weight: bold;">toPredicate</span>(<span style="font-weight: bold; text-decoration: underline;">Root</span>&lt;<span style="font-weight: bold; text-decoration: underline;">T</span>&gt; <span style="font-weight: bold; font-style: italic;">root</span>, <span style="font-weight: bold; text-decoration: underline;">CriteriaQuery</span> <span style="font-weight: bold; font-style: italic;">query</span>, <span style="font-weight: bold; text-decoration: underline;">CriteriaBuilder</span> <span style="font-weight: bold; font-style: italic;">cb</span>);
}
</pre>
</div>
<div class="org-src-container">
<pre class="src src-java"><span style="font-weight: bold;">public</span> <span style="font-weight: bold; text-decoration: underline;">CustomerSpecifications</span> {

    <span style="font-weight: bold;">public</span> <span style="font-weight: bold;">static</span> <span style="font-weight: bold; text-decoration: underline;">Specification</span>&lt;<span style="font-weight: bold; text-decoration: underline;">Customer</span>&gt; <span style="font-weight: bold;">customerHasBirthday</span>() {
        <span style="font-weight: bold;">return</span> (root, query, cb) -&gt;{ 
            <span style="font-weight: bold;">return</span> cb.equal(root.get(Customer_.birthday), today);
        };
    }

    <span style="font-weight: bold;">public</span> <span style="font-weight: bold;">static</span> <span style="font-weight: bold; text-decoration: underline;">Specification</span>&lt;<span style="font-weight: bold; text-decoration: underline;">Customer</span>&gt; <span style="font-weight: bold;">isLongTermCustomer</span>() {
        <span style="font-weight: bold;">return</span> (root, query, cb) -&gt;{ 
            <span style="font-weight: bold;">return</span> cb.lessThan(root.get(Customer_.createdAt), <span style="font-weight: bold;">new</span> LocalDate.<span style="font-weight: bold; text-decoration: underline;">minusYears</span>(2));
        };
    }

}

<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">JpaSpecificationExecutor&lt;Customer&gt;.findAll()</span>
<span style="font-weight: bold;">public</span> <span style="font-weight: bold;">interface</span> <span style="font-weight: bold; text-decoration: underline;">CustomerRepository</span> <span style="font-weight: bold;">extends</span> <span style="font-weight: bold; text-decoration: underline;">JpaRepository</span>&lt;<span style="font-weight: bold; text-decoration: underline;">Customer</span>&gt;, <span style="font-weight: bold; text-decoration: underline;">JpaSpecification</span>&lt;<span style="font-weight: bold; text-decoration: underline;">Customer</span>&gt; {

}

<span style="font-weight: bold; font-style: italic;">//</span>
customerRepository.findAll(hasBirthday());
customerRepository.findAll(isLongTermCustomer());
<span style="font-weight: bold; font-style: italic;">// </span><span style="font-weight: bold; font-style: italic;">Helper class: Specifications.where, and, or</span>
customerRepository.findAll(where(customerHasBirthday()).and(isLongTermCustomer()));

</pre>
</div>
</div>
</div>
</div>
<div class="status" id="postamble">
<p class="date">Date: 2019-5-20</p>
<p class="author">Author: gdme1320</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
